package cn.test3d.service;

import min3d.Shared;
import min3d.core.Object3dContainer;
import min3d.core.Renderer;
import min3d.core.Scene;
import min3d.interfaces.ISceneController;
import min3d.parser.IParser;
import min3d.parser.Parser;
import min3d.vos.Light;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.opengl.GLSurfaceView;
import android.os.Handler;
import android.os.IBinder;
import android.provider.ContactsContract.PhoneLookup;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class Table3DService extends Service implements ISceneController {

	private final float CAM_RADIUS_X = 20;
	private final float CAM_RADIUS_Y = 15;
	private final float CAM_RADIUS_Z = 30;
	private final float ROTATION_SPEED = 1;
	private Object3dContainer monster;
	private float degrees;

	private WindowManager wm;

	public Scene scene;
	protected GLSurfaceView _glSurfaceView;

	protected Handler _initSceneHander;
	protected Handler _updateSceneHander;

	private boolean _renderContinuously;

	private float x;
	private float y;
	private float mTouchStartX;
	private float mTouchStartY;

	final Runnable _initSceneRunnable = new Runnable() {
		public void run() {
			onInitScene();
		}
	};

	final Runnable _updateSceneRunnable = new Runnable() {
		public void run() {
			onUpdateScene();
		}
	};
	private WindowManager.LayoutParams params;
	
	@Override
	public void onCreate() {
		super.onCreate();
		wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

		_initSceneHander = new Handler();
		_updateSceneHander = new Handler();

		//
		// These 4 lines are important.
		//
		Shared.context(this);
		scene = new Scene(this);
		Renderer r = new Renderer(scene);
		Shared.renderer(r);

		_glSurfaceView = new GLSurfaceView(this);
		glSurfaceViewConfig();
		_glSurfaceView.setRenderer(r);
		_glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

		params = new WindowManager.LayoutParams();
		params.height = 150;
		params.width = 300;
		params.type = WindowManager.LayoutParams.TYPE_PHONE; // 设置window type
		params.format = PixelFormat.RGBA_8888; // 设置图片格式，效果为背景透明
		// 设置Window flag
		params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
				| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
		params.gravity = Gravity.LEFT | Gravity.TOP; // 调整悬浮窗口至左上角
		params.setTitle("Toast");

		wm.addView(_glSurfaceView, params);

		_glSurfaceView.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				// 获取相对屏幕的坐标，即以屏幕左上角为原点
				x = event.getRawX();
				y = event.getRawY() - 25; // 25是系统状态栏的高度
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					// 获取相对View的坐标，即以此View左上角为原点
					mTouchStartX = event.getX();
					mTouchStartY = event.getY();
					break;
				case MotionEvent.ACTION_MOVE:
					updateViewPosition();
					break;
				case MotionEvent.ACTION_UP:
					updateViewPosition();
					mTouchStartX = 0;
					mTouchStartY = 0;
					break;
				}
				return true;
			}
		});
	}

	private void updateViewPosition() {
		// 更新浮动窗口位置参数
		params.x = (int) (x - mTouchStartX);
		params.y = (int) (y - mTouchStartY);
		wm.updateViewLayout(_glSurfaceView, params);
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
	}

	/**
	 * Called _after_ scene init (ie, after initScene). Unlike initScene(), gets
	 * called from the UI thread.
	 */
	public void onInitScene() {
	}

	/**
	 * Called _after_ updateScene() Unlike initScene(), gets called from the UI
	 * thread.
	 */
	public void onUpdateScene() {
	}

	@Override
	public void initScene() {
		// TODO Auto-generated method stub
		scene.backgroundColor().setAll(0x00000000);

		scene.lights().add(new Light());

		IParser parser = Parser.createParser(Parser.Type.MAX_3DS,
				getResources(), "cn.test3d:raw/monster_high", false);
		parser.parse();

		monster = parser.getParsedObject();
		monster.scale().x = monster.scale().y = monster.scale().z = .5f;
		monster.position().y = -10;

		scene.addChild(monster);

		scene.camera().target = monster.position();
	}

	@Override
	public void updateScene() {
		// TODO Auto-generated method stub
		float radians = degrees * ((float) Math.PI / 180);
		scene.camera().position.x = (float) Math.cos(radians) * CAM_RADIUS_X;
		scene.camera().position.y = (float) Math.sin(radians) * CAM_RADIUS_Y;
		scene.camera().position.z = (float) Math.sin(radians) * CAM_RADIUS_Z;

		degrees += ROTATION_SPEED;
	}

	@Override
	public Handler getInitSceneHandler() {
		// TODO Auto-generated method stub
		return _initSceneHander;
	}

	@Override
	public Runnable getInitSceneRunnable() {
		// TODO Auto-generated method stub
		return _initSceneRunnable;
	}

	@Override
	public Handler getUpdateSceneHandler() {
		// TODO Auto-generated method stub
		return _updateSceneHander;
	}

	@Override
	public Runnable getUpdateSceneRunnable() {
		// TODO Auto-generated method stub
		return _updateSceneRunnable;
	}

	/**
	 * Any GlSurfaceView settings that needs to be executed before
	 * GLSurfaceView.setRenderer() can be done by overriding this method. A
	 * couple examples are included in comments below.
	 */
	protected void glSurfaceViewConfig() {
		// !important
		_glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
		_glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
	}
}
